//var gis_conf = JSON.parse($("#gis_conf").html());
var resolutions = [];
window.defaultProj = 'EPSG:3857';
window.baseLayers ={};
window.layers = {};
window.center = ol.proj.transform([104.06338, 30.65991], "EPSG:4326", window.defaultProj);
window.controls = {};
window.styles = {};
window.status = 'mormal'; //'measure' ,'draw','realtime'
window.defaultdataformat = new ol.format.GeoJSON({
    defaultDataProjection: "EPSG:4326",
    featureProjection: window.defaultProj
});
var selectStyle = new ol.style.Style({
    lable: 'all',
    fill: new ol.style.Fill({
        color: 'rgba(255, 255, 255, 0.3)'
    }),
    stroke: new ol.style.Stroke({
        color: 'red',
        width: 3
    }),
    image: new ol.style.Circle({
        radius: 11,
        fill: new ol.style.Fill({
            color: 'red'
        }),
        stroke: new ol.style.Stroke({
            color: '#fff',
            width: 3
        })
    }),
    text: new ol.style.Text({
        fill: new ol.style.Fill({ color: '#ff0000' }),
        stroke: new ol.style.Stroke({ color: '#ffffff', width: 3 }),
        textAlign: 'center',
        baseline: 'bottom',
        font: 'normal 14px Arial',
        offsetX: 0,
        offsetY: 15,
        rotation: 0
    })
});
var locatStyle = new ol.style.Style({
    lable: 'all',
    fill: new ol.style.Fill({
        color: 'rgba(255, 255, 255, 0.3)'
    }),
    stroke: new ol.style.Stroke({
        color: 'red',
        width: 3
    }),
    image: new ol.style.Circle({
        radius: 11,
        fill: new ol.style.Fill({
            color: 'mediumblue'
        }),
        stroke: new ol.style.Stroke({
            color: '#fff',
            width: 3
        })
    }),
    text: new ol.style.Text({
        fill: new ol.style.Fill({ color: 'mediumblue' }),
        stroke: new ol.style.Stroke({ color: '#ffffff', width: 3 }),
        textAlign: 'center',
        baseline: 'bottom',
        font: 'normal 14px Arial',
        offsetX: 0,
        offsetY: 20,
        rotation: 0
    })
});
// 初始化底图图层
window.baseLayers["default_base"] = new ol.layer.Tile({
    id: 'default_base',
    title: "默认基础地图",
    visible: true,
    source: new ol.source.OSM()
}),
gis_conf.baseLayers.forEach(layer => {
    if (layer.id =="tianditu_vec_w"){
        window.baseLayers["tianditu_vec_w"] = new ol.layer.Tile({
            id: layer.id,
            title: layer.title,
            visible: false,
            source: new ol.source.XYZ({
                url: 'http://t{0-7}.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=614bbde1ab802e57a16012c6831a8e76'
            })
        });
    } else if (layer.id == "tianditu_cva_w"){
        window.baseLayers["tianditu_cva_w"] = new ol.layer.Tile({
            id: layer.id,
            title: layer.title,
            visible: layer.visible,
            source: new ol.source.XYZ({
                url: 'http://t{0-7}.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=614bbde1ab802e57a16012c6831a8e76'
            })
        });
    } else if (layer.id == "tianditu_ter_w") {
        window.baseLayers["tianditu_ter_w"] = new ol.layer.Tile({
            id: layer.id,
            title: layer.title,
            visible: layer.visible,
            source: new ol.source.XYZ({
                url: 'http://t{0-7}.tianditu.com/DataServer?T=ter_w&x={x}&y={y}&l={z}&tk=614bbde1ab802e57a16012c6831a8e76'
            })
        });
    } else if (layer.id == "tianditu_cta_w") {
        window.baseLayers["tianditu_cta_w"] = new ol.layer.Tile({
            id: layer.id,
            title: layer.title,
            visible: layer.visible,
            source: new ol.source.XYZ({
                url: 'http://t{0-7}.tianditu.com/DataServer?T=cta_w&x={x}&y={y}&l={z}&tk=614bbde1ab802e57a16012c6831a8e76'
            })
        });
    } else if (layer.id == "tianditu_img_w") {
        window.baseLayers["tianditu_img_w"] = new ol.layer.Tile({
            id: layer.id,
            title: layer.title,
            visible: layer.visible,
            source: new ol.source.XYZ({
                url: 'http://t{0-7}.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=614bbde1ab802e57a16012c6831a8e76'
            })
        });
    } else if (layer.id == "tianditu_cia_w") {
        window.baseLayers["tianditu_cia_w"] = new ol.layer.Tile({
            id: layer.id,
            title: layer.title,
            visible: layer.visible,
            source: new ol.source.XYZ({
                url: 'http://t{0-7}.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=614bbde1ab802e57a16012c6831a8e76'
            })
        });
    } else if (layer.id == "bingMapLayer") {
        window.baseLayers["bingMapLayer"] = new ol.layer.Tile({
            id: layer.id,
            title: layer.title,
            visible: layer.visible,
            source: new ol.source.XYZ({
                crossOrigin: 'anonymous',
                tilePixelRatio: 2,
                tileUrlFunction: function (tileCoord) {
                    var z = tileCoord[0];
                    var x = tileCoord[1];
                    var y = -tileCoord[2] - 1;
                    var result = '', zIndex = 0;

                    for (; zIndex < z; zIndex++) {
                        result = ((x & 1) + 2 * (y & 1)).toString() + result;
                        x >>= 1;
                        y >>= 1;
                    }
                    return 'http://dynamic.t0.tiles.ditu.live.com/comp/ch/' + result + '?it=G,VE,BX,L,LA&mkt=zh-cn,syr&n=z&og=111&ur=CN';
                }
            })
        });
    } else if (layer.id == "gaodeMapLayer") {
        window.baseLayers["gaodeMapLayer"] = new ol.layer.Tile({
            id: layer.id,
            title: layer.title,
            visible: layer.visible,
            source: new ol.source.XYZ({
                crossOrigin: 'anonymous',
                url: 'http://webst0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}'
            })
        });
    } else if (layer.id == "googleMapLayer") {
        window.baseLayers["googleMapLayer"] = new ol.layer.Tile({
            id: layer.id,
            title: layer.title,
            visible: layer.visible,
            source: new ol.source.XYZ({
                crossOrigin: 'anonymous',
                url: 'http://www.google.cn/maps/vt/pb=!1m4!1m3!1i{z}!2i{x}!3i{y}!2m3!1e0!2sm!3i345013117!3m8!2szh-CN!3scn!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e0'
            })
        });
    } else if (layer.id == "openCycleMapLayer") {
        window.baseLayers["openCycleMapLayer"] = new ol.layer.Tile({
            id: layer.id,
            title: layer.title,
            visible: layer.visible,
            source: new ol.source.OSM({
                attributions: [
                    'All maps © <a href="https://www.opencyclemap.org/">OpenCycleMap</a>',
                    ol.source.OSM.ATTRIBUTION
                ],
                url: 'https://{a-c}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png' +
                    '?apikey=fedb338d4c194f2fa46bb189851108e0'
            })
        });
    } else if (layer.id == "openTransportMapLayer") {
        window.baseLayers["openTransportMapLayer"] = new ol.layer.Tile({
            id: layer.id,
            title: layer.title,
            visible: layer.visible,
            source: new ol.source.OSM({
                attributions: [
                    'All maps © OpenMap</a>',
                    ol.source.OSM.ATTRIBUTION
                ],
                url: 'https://{a-c}.tile.thunderforest.com/transport/{z}/{x}/{y}.png?apikey=fedb338d4c194f2fa46bb189851108e0'
            })
        });
    }
});

window.map = new ol.Map({
    target: document.getElementById('map'),
    controls: ol.control.defaults({ attribution: false, zoom:false }).extend([
        new ol.control.ScaleLine(),
        // new ol.control.ZoomSlider(),
        // new ol.control.ZoomToExtent(),
        new ol.control.MousePosition({ projection: "EPSG:4326", coordinateFormat: ol.coordinate.createStringXY(4) })]),
    view: new ol.View({
        center: window.center,
        projection: window.defaultProj,
        zoom: 15,
    }),
    interactions: ol.interaction.defaults().extend([
        new ol.interaction.DragRotateAndZoom()
    ]),
});
for (var key in window.baseLayers) {
    window.map.addLayer(window.baseLayers[key]);
}

// 中心点
var marker = new ol.Overlay({
    position: window.center,
    positioning: 'center-center',
    element: document.getElementById('cnetermarker'),
    stopEvent: false
});
window.map.addOverlay(marker);

//弹出层
var popup_element = document.getElementById('popup');
window.popup = new ol.Overlay({
    element: popup_element,
    positioning: 'bottom-center',
    stopEvent: false,
    offset: [0, 0]
});
window.map.addOverlay(window.popup);

//定位层
var locatSource = new ol.source.Vector({
    features: [],
    format: window.defaultdataformat,
});
var locatLayer = new ol.layer.Vector({
    source: locatSource,
    style: function (feature, resolution) {
        locatStyle.getText().setText(feature.get('text'));
        return locatStyle;
    }
});
window.map.addLayer(locatLayer);
window.locatsource = locatSource;


// 地图点击事件处理
window.map.on('click', function (evt) {
    if (window.status == "measure")
        return;
    var _layer = null;
    var feature = window.map.forEachFeatureAtPixel(evt.pixel,
        function (feature, layer) {
            _layer = layer;
            return feature;
        });
    if (feature) {
        var coordinates = feature.getGeometry().getCoordinates();
        window.mapWarpper.requestFeatureInfo(_layer.get("id"), feature.getId());
    }
});
// change mouse cursor when over marker
window.map.on('pointermove', function (e) {
    if (e.dragging) {
        $(popup_element).popover('destroy');
        return;
    }
    var pixel = window.map.getEventPixel(e.originalEvent);
    var hit = window.map.hasFeatureAtPixel(pixel);
    window.map.getTarget().style.cursor = hit ? 'pointer' : '';
});

// 放大缩小
var zoomByDelta = function (delta) {
    var duration_ = 250;
    const map = window.map;
    const view = map.getView();
    if (!view) {
        return;
    }
    const currentResolution = view.getResolution();
    if (currentResolution) {
        const newResolution = view.constrainResolution(currentResolution, delta);
        if (duration_ > 0) {
            if (view.getAnimating()) {
                view.cancelAnimations();
            }
            view.animate({
                resolution: newResolution,
                duration: duration_,
                // easing: easeOut
            });
        } else {
            view.setResolution(newResolution);
        }
    }
};

// 地位到指定的点
var flyTo = function (location, done) {
    var view = window.map.getView();
    var duration = 2000;
    var zoom = view.getZoom();
    var parts = 2;
    var called = false;
    function callback(complete) {
        --parts;
        if (called) {
            return;
        }
        if (parts === 0 || !complete) {
            called = true;
            done(complete);
        }
    }
    view.animate({
        center: location,
        duration: duration
    }, callback);
    view.animate({
        zoom: zoom - 1,
        duration: duration / 2
    }, {
            zoom: zoom,
            duration: duration / 2
        }, callback);
}

//加载图层
var loadvectorLayer = function (obj) {
    var vstyle = window.styles[obj.id];
    if (typeof (vstyle) == 'undefined' && vstyle == null) {
        vstyle = new ol.style.Style({
            // image: new ol.style.Icon({
            //     anchor: [0.5, 0.5],
            //     src: obj.map_icon,
            //     scale: 0.5,
            //     crossOrigin: 'anonymous',
            // }),
            image: new ol.style.Circle({
               radius: 10,
               fill: new ol.style.Fill({
                   color: obj.color,
               }),
               stroke: new ol.style.Stroke({
                   color: '#fff',
                   width: 2
               })
            }),
            text: new ol.style.Text({
                font: '14px FontAwesome,Calibri,sans-serif',
                //text: '\uf041',
                //rotation:-45,
                textAlign: 'left',
                offsetX: 15,
                fill: new ol.style.Fill({
                    color: obj.color
                }),
                stroke: new ol.style.Stroke({
                    color: '#fff',
                    width: 3
                })
            }),
            fill: new ol.style.Fill({
                color: [255, 255, 255, 0.3]
            }),
            stroke: new ol.style.Stroke({
                color: obj.color,
                width: 3
            }),
        });
        window.styles[obj.id] = vstyle;
    }
    var _source = new ol.source.Vector({
        projection: window.defaultProj,
        format: window.defaultdataformat,
        loader: function (extent, resolution, projection) {
            var n_extent = ol.proj.transform(extent, window.defaultProj, "EPSG:4326");
            var _url = obj.vector_url + '?in_bbox=' + n_extent.join(',');
            $.ajax({
                url: _url,
                type: 'GET',
                beforeSend: function (xhr, settings) {
                    xhr.setRequestHeader("Authorization", "Token " + window.token);
                },
                success: function (data) {
                    var format = window.defaultdataformat;
                    var features = format.readFeatures(data);
                    _source.addFeatures(features);
                }
            });
        },
        strategy: ol.loadingstrategy.bbox
    });
    _source.once('change', function (e) {
        if (_source.getState() === 'ready') {
            if (_source.getFeatures().length > 0) {
                var extent = _source.getExtent();
                window.map.getView().fit(extent, window.map.getSize());
                window.map.getView().setZoom(16);
            }
        }
    });
    window.layers[obj.id] = new ol.layer.Vector({
        id: obj.id,
        title: obj.verbose_name,
        visible: false,
        source: _source,
        style: function (feature, resolution) {
            vstyle.getText().setText(resolution < 0.000025 ? feature.get('__str__') : '');
            if (feature.get('color')){
                vstyle.setImage(
                    new ol.style.Circle({
                        radius: 10,
                        fill: new ol.style.Fill({
                            color: feature.get('color'),
                        }),
                        stroke: new ol.style.Stroke({
                            color: '#fff',
                            width: 2
                        })
                    })
                );
                }
            return vstyle;
        }
    });
    window.map.addLayer(window.layers[obj.id]);
    return window.layers[obj.id];
}

// 特性选择----------------------------------------------------
var select = new ol.interaction.Select({
    condition: ol.events.condition.pointerMove | ol.events.condition.singleClick,
    style: selectStyle
});
function enableSelect(enable) {
    if (enable == true) {
        window.map.addInteraction(select);
    } else {
        window.map.removeInteraction(select);
    }
}
// 特性选择----------------------------------------------------


//测量------------------------------------------------------------------
var measureDraw = null, measuresource = null, measurevector = null, sketch = null, measureTooltips = [];
/**
       * Format length output.
       * @param {ol.geom.LineString} line The line.
       * @return {string} The formatted length.
*/
var formatLength = function (line) {
    var length = ol.Sphere.getLength(line, { projection: window.defaultProj });
    var output;
    if (length > 100) {
        output = (Math.round(length / 1000 * 100) / 100) +
            ' ' + 'km';
    } else {
        output = (Math.round(length * 100) / 100) +
            ' ' + 'm';
    }
    return output;
};
/**
       * Format area output.
       * @param {ol.geom.Polygon} polygon The polygon.
       * @return {string} Formatted area.
*/
var formatArea = function (polygon) {
    var area = ol.Sphere.getArea(polygon, { projection: window.defaultProj });
    var output;
    if (area > 10000) {
        output = (Math.round(area / 1000000 * 100) / 100) +
            ' ' + 'km<sup>2</sup>';
    } else {
        output = (Math.round(area * 100) / 100) +
            ' ' + 'm<sup>2</sup>';
    }
    return output;
};


/**
* Creates a new measure tooltip
*/
var measureTooltipElement;
var measureTooltip;
function createMeasureTooltip() {
    if (measureTooltipElement) {
        measureTooltipElement.parentNode.removeChild(measureTooltipElement);
    }
    measureTooltipElement = document.createElement('div');
    measureTooltipElement.className = 'tooltip tooltip-measure';
    measureTooltip = new ol.Overlay({
        element: measureTooltipElement,
        offset: [0, -15],
        positioning: 'bottom-center'
    });
    measureTooltips.push(measureTooltip);
    window.map.addOverlay(measureTooltip);
}

function addInteraction(mtype) {
    if (measuresource == null)
        measuresource = new ol.source.Vector();
    if (measurevector == null) {
        measurevector = new ol.layer.Vector({
            source: measuresource,
            style: new ol.style.Style({
                fill: new ol.style.Fill({
                    color: 'rgba(255, 255, 255, 0.2)'
                }),
                stroke: new ol.style.Stroke({
                    color: 'red',
                    width: 2
                }),
                image: new ol.style.Circle({
                    radius: 7,
                    fill: new ol.style.Fill({
                        color: '#ffcc33'
                    })
                })
            })
        });
        window.map.addLayer(measurevector);
    }
    var gtype = (mtype == 'area' ? 'Polygon' : 'LineString');
    if (measureDraw != null) {
        window.map.removeInteraction(measureDraw);
    }
    measureDraw = new ol.interaction.Draw({
        source: measuresource,
        type: gtype,
        style: new ol.style.Style({
            fill: new ol.style.Fill({
                color: 'rgba(255, 255, 255, 0.2)'
            }),
            stroke: new ol.style.Stroke({
                color: 'rgba(255, 0, 0, 0.5)',
                lineDash: [10, 10],
                width: 2
            }),
            image: new ol.style.Circle({
                radius: 5,
                stroke: new ol.style.Stroke({
                    color: 'rgba(255, 0, 0, 0.7)'
                }),
                fill: new ol.style.Fill({
                    color: 'rgba(255, 255, 255, 0.2)'
                })
            })
        })
    });
    window.map.addInteraction(measureDraw);

    createMeasureTooltip();

    var listener;
    measureDraw.on('drawstart',
        function (evt) {
            // set sketch
            sketch = evt.feature;

            /** @type {ol.Coordinate|undefined} */
            var tooltipCoord = evt.coordinate;

            listener = sketch.getGeometry().on('change', function (evt) {
                var geom = evt.target;
                var output;
                if (geom instanceof ol.geom.Polygon) {
                    output = formatArea(geom);
                    tooltipCoord = geom.getInteriorPoint().getCoordinates();
                } else if (geom instanceof ol.geom.LineString) {
                    output = formatLength(geom);
                    tooltipCoord = geom.getLastCoordinate();
                }
                measureTooltipElement.innerHTML = output;
                measureTooltip.setPosition(tooltipCoord);
            });
        }, this);

    measureDraw.on('drawend',
        function () {
            measureTooltipElement.className = 'tooltip tooltip-static';
            measureTooltip.setOffset([0, -7]);
            // unset sketch
            sketch = null;
            // unset tooltip so that a new one can be created
            measureTooltipElement = null;
            createMeasureTooltip();
            ol.Observable.unByKey(listener);
        }, this);
    window.status == "measure";

}
//清理测量痕迹
function clearMeasure() {
    measuresource = null;
    sketch = null;
    for (var itm in measureTooltips) {
        window.map.removeOverlay(measureTooltips[itm]);
    }
    measureTooltips = [];
    if (measureDraw != null) {
        window.map.removeInteraction(measureDraw);
        measureDraw = null;
    }
    if (measurevector != null) {
        window.map.removeLayer(measurevector);
        measurevector = null;
    }

    window.status == "normal";
}

